#include <math.h>
#include <stdlib.h>
//#include <string.h>
#include "include/typedef.h"

//#include "UP_gdi.h"
//#include "up_math.h"
//const U16 UI_device_width =LCD_WIDTH,UI_device_height = LCD_HEIGHT;


const static Up_U16 low_arrray[256]={
76,137,190,238,281,320,356,388,418,445,470,493,515,
535,554,572,588,604,618,632,645,657,669,680,691,701,
710,719,728,736,744,752,759,766,773,779,785,791,797,802,
808,813,818,823,827,832,836,840,844,848,852,856,859,863,866,
870,873,876,879,882,885,888,890,893,896,898,900,903,905,908,
910,912,914,916,918,920,922,924,926,928,930,
931,933,935,936,938,940,941,943,944,946,947,
949,950,951,953,954,955,957,958,959,960,961,963,964,965,966,967,
968,969,970,971,972,973,974,975,976,977,978,979,980,
981,982,982,983,984,985,986,987,987,988,989,990,990,991,
992,993,993,994,995,995,996,997,997,998,999,999,1000,1000,1001,
1002,1002,1003,1003,1004,1004,1005,1006,
1006,1007,1007,1008,1008,1009,1009,1010,1010,1011,
1011,1012,1012,1013,1013,1014,1014,1015,1015,1015,1016,
1016,1017,1017,1018,1018,1018,1019,1019,1020,1020,1020,
1021,1021,1022,1022,1022,1023,1023,1023,1024,1024,1024,
1025,1025,1025,1026,1026,1026,1027,1027,1027,1028,1028,1028,
1029,1029,1029,1030,1030,1030,1031,1031,1031,
1031,1032,1032,1032,1033,1033,1033,1033,1034,1034,1034,
1035,1035,1035,1035,1036,1036,1036,1036,1037,1037,1037,1037,
1038,1038,1038,1038,1038,1039,1039,1039,1039,1040,1040};

const static Up_U16 mid_array[256]={
0,10,21,31,42,52,63,73,83,93,103,113,122,132,142,151,161,170,179,189,198,207,216
,224,233,242,251,259,267,276,284,292,300,308,316,324,332,340,347,355,362,369,377
,384,391,398,405,411,418,425,431,438,444,451,457,463,469,475,481,487,492,498,504
,509,514,520,525,530,535,540,545,550,554,559,564,568,572,577,581,585,589,593,597
,601,604,608,611,615,618,621,625,628,631,634,636,639,642,644,647,649,652,654,656
,658,660,662,664,666,667,669,670,672,673,674,675,676,677,678,679,680,680,681,681
,682,682,682,682,683,682,682,682,682,681,681,680,680,679,678,677,676,675,674,673
,672,670,669,667,666,664,662,660,658,656,654,652,649,647,644,642,639,636,634,631
,628,625,621,618,615,611,608,604,601,597,593,589,585,581,577,572,568,564,559,554
,550,545,540,535,530,525,520,514,509,504,498,492,487,481,475,469,463,457,451,444
,438,431,425,418,411,405,398,391,384,377,369,362,355,347,340,332,324,316,308,300
,292,284,276,267,259,251,242,233,224,216,207,198,189,179,170,161,151,142,132,122
,113,103,93,83,73,63,52,42,31,21,10,0,0};


/*  for lightening  */
static Up_U16  *highlights_add = 0;
static Up_U16  *midtones_add = 0;
static Up_U16 *shadows_add = 0;

/*  for darkening  */
static Up_U16  *highlights_sub = 0;
static Up_U16  *midtones_sub = 0;
static Up_U16  *shadows_sub = 0;
void MIOSHOW_color_balance_transfer_init (void)
{
  	Up_S32 i;
	if(!shadows_add)
	{
		shadows_add = (Up_U16*)malloc(256*sizeof(Up_U16));
	}	
	if(!shadows_sub)
	{
		shadows_sub = (Up_U16*)malloc(256*sizeof(Up_U16));
	}	
	if(!midtones_add)
	{
		midtones_add = (Up_U16*)malloc(256*sizeof(Up_U16));
	}	
	if(!midtones_sub)	
	{
		midtones_sub = (Up_U16*)malloc(256*sizeof(Up_U16));
	}	
	if(!highlights_add)
	{
		highlights_add = (Up_U16*)malloc(256*sizeof(Up_U16));
	}	
	if(!highlights_sub)
	{
		highlights_sub = (Up_U16*)malloc(256*sizeof(Up_U16));
	}	
	for (i = 0; i < 256; i++)
	{
		shadows_add[i]          = low_arrray[i];
		shadows_sub[255 - i]    = low_arrray[i];
		midtones_add[i]         = mid_array[i];
		midtones_sub[i]         = mid_array[i];
		highlights_add[255 - i] = low_arrray[i];
		highlights_sub[i]       = low_arrray[i];
	}
}

void MIOSHOW_color_balance_transfer_exit(void)
{
	if(shadows_add)
	{
		free(shadows_add);
		shadows_add = 0;
	}
	if(shadows_sub)
	{
		free(shadows_sub);
		shadows_sub = 0;
	}	
	if(midtones_add)
	{
		free(midtones_add);
		midtones_add = 0;
	}	
	if(midtones_sub)
	{
		free(midtones_sub);
		midtones_sub = 0;
	}	
	if(highlights_add)
	{
		free(highlights_add);
		highlights_add = 0;
	}	
	if(highlights_sub)
	{
		free(highlights_sub);
		highlights_sub = 0;
	}	
}

static void UUPHOTO_HUE_TO_COLOR(S32 hue, S32 m1, S32 m2, U8 *V)
{
    S32 h;
    h = (hue + 360) % 360;
    if(h < 60)				/*60 = 360 / 6;*/
        *V = m1 + (m2 - m1) * h / 60;
    else if(h < 180)		/*180 = 360 / 2;*/
        *V = m2;
    else if(h < 240)		/*240 = 360 * 2 / 3;*/
        *V = m1 + (m2 - m1) * (240 - h) / 60;
    else
        *V = m1;
}

//ɫ�ʵ���
/* H [0, 360], L [0, 255], S [0, 255]. */
static void uuphoto_editor_rgb_to_hsl(S32 r, S32 g, S32 b, 
                                      S32 *hue, S32 *saturation, S32 *lightness)
{
    U8 cmax, cmin, delta;
    S32 h, l, s;

    cmax = UUPHOTO_MAX(r, UUPHOTO_MAX(g, b));
    cmin = UUPHOTO_MIN(r, UUPHOTO_MIN(g, b));
    l = (cmax + cmin + 1) >> 1;

	if(cmax == cmin) {
		h = 0;
		s = 0;
	} else {
        delta = cmax - cmin;
        if(l < 128) {
            s = (delta << 8) / (cmax + cmin);
        } else {
            s = (delta << 8) / (511 - cmax - cmin);
        }

        if(r == cmax) {
            h = 60 * (g - b) / delta;
            if(g < b) {
                h += 360;
            }
        } else if(g == cmax) {
            h = 120 + 60 * (b - r) / delta;
        } else{
            h = 240 + 60 * (r - g) / delta;
        }
    }
    *hue = h;
    *saturation = s;
    *lightness = l;

}

/* H [0, 360], L [0, 255], S [0, 255]. */
static void uuphoto_editor_hsl_to_rgb(S32 hue, S32 saturation, S32 lightness, 
                                      U8 *red, U8 *green, U8 *blue){
	S32 q, p;

	if(saturation == 0)
	{
		*red = *green = *blue = lightness;
	}
	else
	{
		if(lightness < 128)
			q = lightness + (lightness * saturation >> 8);
		else
			q  = lightness + saturation - (lightness * saturation >> 8);
		p = (lightness << 1) - q;
       
        UUPHOTO_HUE_TO_COLOR(hue + 120, p, q, red);
        UUPHOTO_HUE_TO_COLOR(hue, p, q, green);
        UUPHOTO_HUE_TO_COLOR(hue - 120, p, q, blue);
	}
}
/*add by ivan 2011-04-27*/
void* Up_Memcpy(void* destin,void* source,Up_U32 n)
{
	return memcpy(destin,source,n);
} 

gdi_color gdi_color_get(U8 *buf,int x, int y,int width)
{
    return *(U16*) (buf + ((y * width+ x) << 1));
}


void gdi_color_put(U8 *buf,int x, int y,int width, gdi_color c)
{

    *(U16*) (buf + ((y * width + x) << 1)) = (U16) c;
}

void uuphoto_hsl_to_rgb(int hue, int saturation, int lightness, int * red, int * green, int * blue)
{
	int m1, m2;

	if(saturation == 0)
	{
		*red = *green = *blue = lightness;
	}
	else
	{
		if(lightness < 128)
			m2 = lightness + (lightness * saturation >> 8);
		else
			m2 = lightness + saturation - (lightness * saturation >> 8);
		m1 = lightness * 2 - m2;
		HUE_TO_COLOR(hue + 120, m1, m2, *red);
		HUE_TO_COLOR(hue, m1, m2, *green);
		HUE_TO_COLOR(hue - 120, m1, m2, *blue);
	}
}


static void  UUPHOTO_REMOVE_REDEYE_PIXEL(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
    U8 adjusted_red, adjusted_green, adjusted_blue, adjusted_threshold, temp_r;
    S32  strength = 100;//uuphoto_editor_remove_redeye_strength; 

    adjusted_threshold = (strength - 64) << 1;
    adjusted_red = UUPHOTO_RGB565_GET_R(wPixel) * REDEYE_R_FACTOR >> 8;
    adjusted_green = UUPHOTO_RGB565_GET_G(wPixel) << 2;
    adjusted_blue = UUPHOTO_RGB565_GET_B(wPixel) * REDEYE_B_FACTOR >> 8;
    if(adjusted_red >= adjusted_green - adjusted_threshold &&
        adjusted_red >= adjusted_blue - adjusted_threshold) {
        temp_r = (FIX_VALUE((adjusted_green + adjusted_blue), 0, 255) >> 3);
        *pr = (temp_r * strength + UUPHOTO_RGB565_GET_R(wPixel) * (128 - strength)) >> 7;
        *pr = (temp_r * strength + UUPHOTO_RGB565_GET_R(wPixel) * (128 - strength)) >> 7;
    } else {
        *pr = UUPHOTO_RGB565_GET_R(wPixel);
    }
    *pg = UUPHOTO_RGB565_GET_G(wPixel);
    *pb = UUPHOTO_RGB565_GET_B(wPixel);
}


// ʹ�õ�����ɫ�ķ����������Ч���õ�������ů�ƣ���������ƫɫ����Ƭ
static void  UUPHOTO_CHANGE_TO_COLDBLUE(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
	S32 src_r, src_g, src_b;
	S32 lightness, cmax, cmin;
	S32 dst_r, dst_g, dst_b;

	src_r = UUPHOTO_RGB565_GET_R(wPixel) << 3;
	src_g = UUPHOTO_RGB565_GET_G(wPixel) << 2;
	src_b = UUPHOTO_RGB565_GET_B(wPixel) << 3;
	cmax = UUPHOTO_MAX(src_r, UUPHOTO_MAX(src_g, src_b));
	cmin = UUPHOTO_MIN(src_r, UUPHOTO_MIN(src_g, src_b));
	lightness = (cmax + cmin + 1) >> 1;
	uuphoto_hsl_to_rgb(214, 240, lightness, &dst_r, &dst_g, &dst_b);
	// ʹ��25%����ɫЧ��
	*pr = (src_r * 3 + dst_r) >> 2 >> 3;
	*pg = (src_g * 3 + dst_g) >> 2 >> 2;
	*pb = (src_b * 3 + dst_b) >> 2 >> 3;
}

static void  UUPHOTO_CHANGE_TO_COLDGREEN(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
	S32 src_r, src_g, src_b;
	S32 lightness, cmax, cmin;
	S32 dst_r, dst_g, dst_b;

	src_r = UUPHOTO_RGB565_GET_R(wPixel) << 3;
	src_g = UUPHOTO_RGB565_GET_G(wPixel) << 2;
	src_b = UUPHOTO_RGB565_GET_B(wPixel) << 3;
	cmax = UUPHOTO_MAX(src_r, UUPHOTO_MAX(src_g, src_b));
	cmin = UUPHOTO_MIN(src_r, UUPHOTO_MIN(src_g, src_b));
	lightness = (cmax + cmin + 1) >> 1;
	uuphoto_hsl_to_rgb(120, 221, lightness, &dst_r, &dst_g, &dst_b);
	// ʹ��25%����ɫЧ��
	*pr = (src_r * 3 + dst_r) >> 2 >> 3;
	*pg = (src_g * 3 + dst_g) >> 2 >> 2;
	*pb = (src_b * 3 + dst_b) >> 2 >> 3;
}

static  void UUPHOTO_CHANGE_TO_WARMYELLOW(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
	S32 src_r, src_g, src_b;
	S32 lightness, cmax, cmin;
	S32 dst_r, dst_g, dst_b;

	src_r = UUPHOTO_RGB565_GET_R(wPixel) << 3;
	src_g = UUPHOTO_RGB565_GET_G(wPixel) << 2;
	src_b = UUPHOTO_RGB565_GET_B(wPixel) << 3;
	cmax = UUPHOTO_MAX(src_r, UUPHOTO_MAX(src_g, src_b));
	cmin = UUPHOTO_MIN(src_r, UUPHOTO_MIN(src_g, src_b));
	lightness = (cmax + cmin + 1) >> 1;
	uuphoto_hsl_to_rgb(30, 230, lightness, &dst_r, &dst_g, &dst_b);
	// ʹ��25%�ĳ�ɫЧ��
	*pr = (src_r * 3 + dst_r) >> 2 >> 3;
	*pg = (src_g * 3 + dst_g) >> 2 >> 2;
	*pb = (src_b * 3 + dst_b) >> 2 >> 3;
}


static  void UUPHOTO_CHANGE_TO_RETRO(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
    U8 gray, delta;

    gray = (UUPHOTO_RGB565_GET_R(wPixel) + UUPHOTO_RGB565_GET_G(wPixel) + UUPHOTO_RGB565_GET_B(wPixel)) << 1;
    if(gray < 128) {
        delta = gray >> 2;
    } else {
        delta = (0xFF - gray) >> 2;
    }
    *pr = (gray + delta) >> 3;
    *pg = gray >> 2;
    *pb = (gray - delta) >> 3;
}
static  void UUPHOTO_CHANGE_TO_FILM(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
    *pr = 31 - UUPHOTO_RGB565_GET_R(wPixel);
    *pg = 63 - UUPHOTO_RGB565_GET_G(wPixel);
    *pb = 31 - UUPHOTO_RGB565_GET_B(wPixel);
}

static void UUPHOTO_CHANGE_TO_GRAY(U16 wPixel, U8 *pr, U8 *pg, U8 *pb)
{
    U8 gray;

    gray = (UUPHOTO_RGB565_GET_R(wPixel) + UUPHOTO_RGB565_GET_G(wPixel) + UUPHOTO_RGB565_GET_B(wPixel));

    *pr = gray >> 3;
    *pg = gray >> 2;
    *pb = gray >> 3;
}
static void uuphoto_editor_function_remove_redeye_pixel(U16 wPixel, U8 *r, U8 *g, U8 *b)
{
    U8 adjusted_red, adjusted_green, adjusted_blue, adjusted_threshold, temp_r;
    S32  strength = 100;//uuphoto_editor_remove_redeye_strength;

    adjusted_threshold = (strength - 64) << 1;
    adjusted_red = UUPHOTO_RGB565_GET_R(wPixel) * REDEYE_R_FACTOR >> 8;
    adjusted_green = UUPHOTO_RGB565_GET_G(wPixel) << 2;
    adjusted_blue = UUPHOTO_RGB565_GET_B(wPixel) * REDEYE_B_FACTOR >> 8;

    if(adjusted_red >= adjusted_green - adjusted_threshold &&
        adjusted_red >= adjusted_blue - adjusted_threshold) {
        temp_r = (FIX_VALUE((adjusted_green + adjusted_blue), 0, 255) >> 3);
        *r = (temp_r * strength + UUPHOTO_RGB565_GET_R(wPixel) * (128 - strength)) >> 7;      
    } else {
        *r = UUPHOTO_RGB565_GET_R(wPixel);
    }
    *g = UUPHOTO_RGB565_GET_G(wPixel);
    *b = UUPHOTO_RGB565_GET_B(wPixel);
}


void uuphoto_editor_function_change_studio_ext(ImageEditorArea *iea)
{
	U16 i,ii,j,jj,w,h;
	gdi_color pixel;
	U8 *buf0,*buf1; 
	U8 r,g,b;
	U16 *tt;
	U32 counter = 0;
  
	ii = i = iea->rect->x;
	jj = j = iea->rect->y;
	w = iea->rect->width;
	h = iea->rect->height;
	tt = (U16*)iea->para;
	buf0 = (U8*)iea->buf0;
	buf1 = (U8*)iea->buf1;

	Up_Memcpy((void*)buf1,(void*)buf0,w*h*BPP);

	
     switch(*tt) {
        case uuphoto_editor_cold_blue:
		for(i = jj ;i<(jj+h);i++)
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf1,j,i,w);
			UUPHOTO_CHANGE_TO_COLDBLUE(pixel,&r,&g,&b);
			pixel = UUPHOTO_RGB565(r,g,b);			
			gdi_color_put(buf0,j,i,w,pixel);
			counter++;
		}
            break;
            
        case uuphoto_editor_cold_green:
		for(i = jj ;i<(jj+h);i++)
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf1,j,i,w);
			UUPHOTO_CHANGE_TO_COLDGREEN(pixel,&r,&g,&b);
			pixel = UUPHOTO_RGB565(r,g,b);			
			gdi_color_put(buf0,j,i,w,pixel);
		}
            break;
            
        case uuphoto_editor_warm_yellow:
		for(i = jj ;i<(jj+h);i++)
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf1,j,i,w);
			UUPHOTO_CHANGE_TO_WARMYELLOW(pixel,&r,&g,&b);
			pixel = UUPHOTO_RGB565(r,g,b);			
			gdi_color_put(buf0,j,i,w,pixel);
		}
            break;
            
        case uuphoto_editor_retro:
		for(i = jj ;i<(jj+h);i++)
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf1,j,i,w);
			UUPHOTO_CHANGE_TO_RETRO(pixel,&r,&g,&b);
			pixel = UUPHOTO_RGB565(r,g,b);			
			gdi_color_put(buf0,j,i,w,pixel);
		}
            break;

        case uuphoto_editor_gray:
		for(i = jj ;i<(jj+h);i++)
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf1,j,i,w);
			UUPHOTO_CHANGE_TO_GRAY(pixel,&r,&g,&b);
			pixel = UUPHOTO_RGB565(r,g,b);
			gdi_color_put(buf0,j,i,pixel,w);
		}
            break;

        case uuphoto_editor_film:
		for(i = jj ;i<(jj+h);i++)
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf1,j,i,w);
			UUPHOTO_CHANGE_TO_FILM(pixel,&r,&g,&b);
			pixel = UUPHOTO_RGB565(r,g,b);
			gdi_color_put(buf0,j,i,pixel,w);
		}
            break;
     }
	 
    //	Up_GDIClearLayerBuffer(GDI_LAYER_1);
    //   Up_ScreenUpdate(0);	
}

/*
 * The equations: g(r) = exp (- r^2 / (2 * sigma^2))
 *                   r = sqrt (x^2 + y ^2)
 */
void uuphoto_make_curve(double sigma, S32 *length,S32 *curve)
{
	double  sigma2, l;
	S32     temp;
	S32     i, n, ll;
    S32    *temp_curve;

	sigma2 = 2 * sigma * sigma;
	l = sqrt(-sigma2 * log(1.0 / 255.0));

	n = (S32)(ceil(l) * 2);
	if ((n % 2) == 0)
		n += 1;

	*length = n / 2;
    ll = n / 2;

    temp_curve = (S32 *)curve;
	temp_curve += ll;
	temp_curve[0] = 255;

	for (i = 1; i <= ll; i++)
	{
		temp = (S32)(exp(- (i * i) / sigma2) * 255);
		temp_curve[-i] = temp;
		temp_curve[i] = temp;
	}

}
#if 0
		ImageEditorArea iea;
		SoftGlowData sgd;
		iea.buf0 = up_get_layer_buffer(GDI_LAYER_0);
		iea.buf1 = up_get_layer_buffer(GDI_LAYER_1);	
		iea.rect = &psRect;
		sgd.blur = 8;
		sgd.light = 75;
		sgd.curve = (void*)Up_Malloc(1024 * 2);
		iea.para = (void*)&sgd;
		uuphoto_editor_function_softglow(&iea);
		Up_Free((void*)sgd.curve);

#endif

void uuphoto_editor_function_softglow(ImageEditorArea *iea)
{
    U16 *buf_ptr, *temp_buf, *dst_data, *src_data, wPixel, *column_ptr;
    U16 *src_buf;
    S32 width, height, length, w, h;
    S32 uuphoto_sum, i, tmp = 0, cr, cg, cb, cur_radius;
    S32 light, ri, sumlight, averlight;
    double radius, std_dev;
    U16 *temp_line;
    S32  cur_min, cur_max;
    S32 *cur_curve, * curve_ptr, curve_value;
    SoftGlowData *sgd = (SoftGlowData*)iea->para;

    if(sgd->blur <= 0)
        return;

	width = iea->rect->width;
    height = iea->rect->height;
    buf_ptr = (U16 *)iea->buf0;//dst
    temp_buf = (U16 *)iea->buf1;//src
	
    temp_line = (U16*)malloc(960*sizeof(U16));
    Up_Memcpy((void*)iea->buf1,(void*)iea->buf0,width*height*BPP);
    

    sumlight = uuphoto_sum = 0;
    radius = abs(sgd->blur) * 1.4;
    std_dev = sqrt(-(radius * radius) / (2 * log(1.0 / 255.0)));
    uuphoto_make_curve(std_dev, &length,(S32*)sgd->curve);
    cur_curve = (S32*)sgd->curve; 
    cur_radius = length*2 + 1;


    /*  First, the vertical pass  */
    for(w = 0; w < width; w++) {
        dst_data = buf_ptr + w+iea->rect->x+iea->rect->y*width;
        src_data = temp_buf + w+ iea->rect->x+iea->rect->y*width;
        column_ptr = temp_line;
        for(h = 0; h < height; h++) {
            *column_ptr = *src_data;
            column_ptr++;
            src_data += width;//must be lcd width
        }
        
        for(h = 0; h < height; h++) {
            ri = h - length;
            cur_min = UUPHOTO_MAX(0, ri);
            cur_max = UUPHOTO_MIN(height, ri + cur_radius);
            src_buf = temp_line + cur_min;
            curve_ptr = cur_curve + (cur_min - ri);
            for(i = cur_max - cur_min; i > 0; i--) {                
                wPixel = *src_buf;
                src_buf++;
                light = (UUPHOTO_RGB565_GET_R(wPixel) + UUPHOTO_RGB565_GET_G(wPixel) + UUPHOTO_RGB565_GET_B(wPixel)) << 1;
                curve_value = *curve_ptr;
                curve_ptr++;
                sumlight += (light * curve_value * sgd->light >> 7);
                uuphoto_sum += curve_value;
            }
            wPixel = *dst_data;
            averlight = sumlight / uuphoto_sum;
            *dst_data = averlight;
            dst_data += width;
            sumlight = uuphoto_sum = 0; 
        }
    }

    sumlight = uuphoto_sum = 0;
    
    /*  Now the horizontal pass  */
    for(h = 0; h < height; h++) {
        Up_Memcpy(temp_line, buf_ptr + h * width+iea->rect->x+iea->rect->y*width, width * 2);
        src_data = temp_buf + h * width+iea->rect->x+iea->rect->y*width;
        dst_data = buf_ptr + h * width+iea->rect->x+iea->rect->y*width;
        for(w = 0; w < width; w++) {
            ri = w - length;
            cur_min = UUPHOTO_MAX(0, ri);
            cur_max = UUPHOTO_MIN(width, ri + cur_radius);
            src_buf = temp_line + cur_min;
            curve_ptr = cur_curve + (cur_min - ri);
            for(i = cur_max - cur_min; i > 0; i--) { 
                wPixel = *src_buf;
                src_buf++;
                curve_value = *curve_ptr;
                curve_ptr++;
                sumlight += wPixel * curve_value;
                uuphoto_sum += curve_value;                 
            }
            
            averlight = sumlight / uuphoto_sum;
            wPixel = *src_data;
            cr = 255 - UUPHOTO_INT_MULT((255 - (UUPHOTO_RGB565_GET_R(wPixel) << 3)),
                                 (255 - averlight), tmp);
            cg = 255 - UUPHOTO_INT_MULT((255 - (UUPHOTO_RGB565_GET_G(wPixel) << 2)),
                                 (255 - averlight), tmp);
            cb = 255 - UUPHOTO_INT_MULT((255 - (UUPHOTO_RGB565_GET_B(wPixel) << 3)),
                                 (255 - averlight), tmp);

            *dst_data = UUPHOTO_RGB565(cr >> 3, cg >> 2, cb >> 3);          
            sumlight = uuphoto_sum = 0;
            dst_data++;  
            src_data++;
        }
    } 

	free((void*)temp_line);
 //      Up_ScreenUpdate(0);	
}


//���벹��
void uuphoto_editor_function_fill_light(ImageEditorArea *iea)
{
    U16 *src, *dest, *dst_data, *src_data, wPixel;
    U8 r, g, b, l;
    S32 i, width, height, length, strength;	

	width = iea->rect->width;
    height = iea->rect->height;
    length = width * height;
	
    Up_Memcpy((void*)iea->buf1,(void*)iea->buf0,width*height*BPP);
	
   
    dest = (U16 *)iea->buf0;
    src = (U16 *)iea->buf1;
    src_data = src;
    dst_data = dest;
    strength = *(S32*)iea->para;

    for(i = 0; i < length; i++) {
        wPixel = *(src_data + iea->rect->y*width+iea->rect->x+i);
        r = UUPHOTO_RGB565_GET_R(wPixel);
        g = UUPHOTO_RGB565_GET_G(wPixel);
        b = UUPHOTO_RGB565_GET_B(wPixel);
        l = (r + g + b) << 1;
        r = r + ((r - (r * l >> 8)) * strength >> 7);
        g = g + ((g - (g * l >> 8)) * strength >> 7);
        b = b + ((b - (b * l >> 8)) * strength >> 7);
        if(r > 31)
            r = 31;
        if(g > 63)
            g = 63;
        if(b > 31)
            b = 31;
        *(dst_data + iea->rect->y*width+iea->rect->x+i) = UUPHOTO_RGB565(r, g, b);
    }

       //Up_ScreenUpdate(0);		
}



void uuphoto_editor_function_change_hue_ext(ImageEditorArea *iea)   //(gdi_layer_struct *base_layer,S32 delta)
{
    U16 *buf_ptr, *temp_buf, *line_buf;
    U16 *src_buf, *src_line_buf, *temp_src_buf;
    U16 wPixel;
    S32 w, h, width, height, start_draw_x, start_draw_y;
    S32 hue, saturation, lightness, saturation_delta;
    U8 r, g, b;
    S32 device_width;   

    start_draw_x = iea->rect->x;
    start_draw_y = iea->rect->y;
    width = iea->rect->width;
    height = iea->rect->height;
	device_width = width;
    saturation_delta = *(S32*)iea->para ;

    Up_Memcpy((void*)iea->buf1,(void*)iea->buf0,width*height*BPP);
    buf_ptr = (U16 *)iea->buf0;
    buf_ptr = buf_ptr + start_draw_y * device_width + start_draw_x;
    line_buf = buf_ptr;
    src_buf = (U16 *)iea->buf1;
    src_buf = src_buf + start_draw_y * device_width + start_draw_x;
    src_line_buf = src_buf;      

    for(h = height; h > 0; h--)
    {
        temp_buf = line_buf;
        temp_src_buf = src_line_buf;
        for(w = width; w > 0; w--) 
        {
            wPixel = *temp_src_buf;
            uuphoto_editor_rgb_to_hsl((UUPHOTO_RGB565_GET_R(wPixel) << 3), 
                                      (UUPHOTO_RGB565_GET_G(wPixel) << 2),
                                      (UUPHOTO_RGB565_GET_B(wPixel) << 3),
                                      &hue, &saturation, &lightness);
			if(saturation > 200)
            {
				saturation = saturation + 0;
			}
            saturation += saturation_delta;
            saturation = FIX_VALUE(saturation, 0, 240);
            uuphoto_editor_hsl_to_rgb(hue, saturation, lightness,
                                      &r, &g, &b);
            r = r >> 3;
            g = g >> 2;
            b = b >> 3;
            *temp_buf = UUPHOTO_RGB565(r, g, b);
			temp_buf++;
            temp_src_buf++;
        }
        src_line_buf += device_width;
        line_buf += device_width;
    }
       //Up_ScreenUpdate(0);	
}


void MIOSHOW_editor_bright_contrast_create_lookup_table(BrightnessContrastData *bright_data)
{
    S32 brightness, contrast, i, value;
    float slant;

    brightness = bright_data->brightness;
    contrast = bright_data->contrast;
    brightness = _TO_FIXED_22_10(brightness) / bright_data->mean_value;
    slant = (float)contrast / bright_data->mean_value;
    slant = (float)tan((slant + 1) * MIOSHOW_PI_4);
    contrast = (S32)(slant * 1024);
         
    if(brightness != 0 || contrast != 0) {
        for(i = 0; i < 64; i++) {
            value = _TO_FIXED_22_10(i) >> 6;
            if(brightness != 0) {
                value = value + _FIXED_22_10_FLOOR(value * brightness);  
            }
            if(contrast != 0) {
                value = _FIXED_22_10_FLOOR((value - 512) * contrast) + 512;
            }
            value = value >> 4;
            value = FIX_VALUE(value, 0, 63);
         
            bright_data->lookup_table[i] = (U8)value;
        }
    } else {
        for(i = 0; i < 64; i ++) {
            bright_data->lookup_table[i] = (U8)i;
        }
    }
}

void MIOSHOW_editor_function_change_brightness_contrast(ImageEditorArea *iea)
                                //,gdi_layer_struct *base_layer)
{
    BrightnessContrastData *bright_data = (BrightnessContrastData*)iea->para;
    Up_U16 *buf_ptr, *line_buf, *temp_buf, *src_buf, *src_line_buf, *temp_src_buf;
    Up_U16 wPixel;
    Up_S32 w, h, width, height, start_draw_x, start_draw_y;
    Up_U8 r, g, b;
    Up_U8 * lookup_table;
	width = iea->rect->width;
    height = iea->rect->height;
    Up_S32 device_width = width ;  

    Up_Memcpy((void*)iea->buf1,(void*)iea->buf0,width*height*BPP);
    MIOSHOW_editor_bright_contrast_create_lookup_table(bright_data);
    lookup_table = bright_data->lookup_table;
    start_draw_x = iea->rect->x;
    start_draw_y = iea->rect->y;
    width = iea->rect->width;
    height = iea->rect->height;
    
    buf_ptr = (U16 *)iea->buf0;
    buf_ptr = buf_ptr + start_draw_y * device_width + start_draw_x;
    src_buf = (U16 *)iea->buf1;
    src_buf = src_buf + start_draw_y * device_width + start_draw_x;
    line_buf = buf_ptr;
    src_line_buf = src_buf;

    for(h = height; h > 0; h--) {
        temp_buf = line_buf;
        temp_src_buf = src_line_buf;
        for(w = width; w > 0; w--) {
            wPixel = *temp_src_buf;
            r = lookup_table[MIOSHOW_RGB565_GET_R(wPixel) << 1] >> 1;
            g = lookup_table[MIOSHOW_RGB565_GET_G(wPixel)];
            b = lookup_table[MIOSHOW_RGB565_GET_B(wPixel) << 1] >> 1;
            
            *temp_buf = MIOSHOW_RGB565(r, g, b);
            temp_buf++;
            temp_src_buf++;
        }
        line_buf += device_width;
        src_line_buf += device_width;
    }
    
}

void change_bc(Up_S32 brightness,Up_S32 contrast,ImageEditorArea *iea)
{

	BrightnessContrastData bcd ;//= up_zero_alloc(sizeof(BrightnessContrastData));

	bcd.brightness = brightness;
	bcd.contrast = contrast;
	bcd.mean_value = 100;
	//.buf0 = (Up_U8*)up_get_layer_buffer(0);
	//iea.buf1 = (Up_U8*)up_get_layer_buffer(1);
	//iea.rect = &GIP->editorArea->area;
	iea->para = (void*)&bcd;
	MIOSHOW_editor_function_change_brightness_contrast(iea);
}

void MIOSHOW_hsl_to_rgb(int hue, int saturation, int lightness, int * red, int * green, int * blue)
{
	int m1, m2;

	if(saturation == 0)
	{
		*red = *green = *blue = lightness;
	}
	else
	{
		if(lightness < 128)
			m2 = lightness + (lightness * saturation >> 8);
		else
			m2 = lightness + saturation - (lightness * saturation >> 8);
		m1 = lightness * 2 - m2;
		HUE_TO_COLOR(hue + 120, m1, m2, *red);
		HUE_TO_COLOR(hue, m1, m2, *green);
		HUE_TO_COLOR(hue - 120, m1, m2, *blue);
	}
}

void MIOSHOW_CHANGE_TO_COLOR(U16 wPixel, U8 *pr, U8 *pg, U8 *pb,S32 hue,S32 sat,S32 percet)
{
	S32 src_r, src_g, src_b;
	S32 lightness, cmax, cmin;
	S32 dst_r, dst_g, dst_b;
	;

	src_r = MIOSHOW_RGB565_GET_R(wPixel) << 3;
	src_g = MIOSHOW_RGB565_GET_G(wPixel) << 2;
	src_b = MIOSHOW_RGB565_GET_B(wPixel) << 3;
	cmax = MIOSHOW_MAX(src_r, MIOSHOW_MAX(src_g, src_b));
	cmin = MIOSHOW_MIN(src_r, MIOSHOW_MIN(src_g, src_b));
	lightness = (cmax + cmin + 1) >> 1;

	MIOSHOW_hsl_to_rgb(hue, sat,lightness, &dst_r, &dst_g, &dst_b);
	*pr = (src_r *(255-percet) + percet*dst_r)>>3>>8;
	*pg = (src_g *(255-percet) + percet*dst_g)>>2>>8;
	*pb = (src_b *(255-percet) + percet*dst_b)>>3>>8;
}

void MIOSHOW_add_color(ImageEditorArea *iea)
{
	U16 i,ii,j,jj,w,h;
	gdi_color pixel;
	U8 *buf0;
	U8 r,g,b;
	AddColorData *acd = iea->para;
	//IPProgress *ipp;
	Up_S32 hue,sat,percet;
	ii = iea->rect->x;
	jj = iea->rect->y;
	h = iea->rect->width;
	w = iea->rect->height;
	buf0 = (U8*)iea->buf0;
	hue = acd->hue;
	sat = acd->sat;
	percet = acd->percent;
	hue = CLAMP(hue, 0, 360);
	sat = CLAMP(sat, 0, 255);	
	percet = CLAMP(percet, 0, 255);
	//ipp = progress_bar_begin(rect(IPPROGRESS_BAR_X,IPPROGRESS_BAR_Y,IPPROGRESS_BAR_WIDTH,IPPROGRESS_BAR_HEIGHT),upcolor_to_gdicolor(LIGHT_RED));	
	//progress_bar_set_data(ipp,h);
	for(i = jj ;i<(jj+h);i++)
	{
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = gdi_color_get(buf0,j,i,w);
			MIOSHOW_CHANGE_TO_COLOR(pixel,&r,&g,&b,hue,sat,percet);
			pixel = MIOSHOW_RGB565(r,g,b);			
			gdi_color_put(buf0,j,i,w,pixel);
		}
		//progress_bar_inc(ipp);
	}
	//progress_bar_end(&ipp);
}

void addcolor(Up_S32 hue,Up_S32 sat,Up_S32 percent,ImageEditorArea *iea)
{
	//ImageEditorArea iea;
	AddColorData acd;
	acd.hue = hue;
	acd.sat = sat;
	acd.percent = percent;
	//iea->buf0 = (Up_U8*)up_get_layer_buffer(0);
	//iea->buf1 = (Up_U8*)up_get_layer_buffer(1);
	//iea.rect = &GIP->editorArea->area;
	iea->para = (void*)&acd;
	
	MIOSHOW_add_color(iea);
}

GDIColor up_gd_color_to_rgb_16(gdi_color c)
{
	int t;
	GDIColor clr__;
	GDIColor *clr;
	
	clr = &clr__;
	
    clr->alpha = 0xFF;

    t = ((Up_U32) (((c) & 0xf800) >> 8));
    clr->r = t | (t>>5);
    
    t = ((Up_U32) (((c) & 0x07e0) >> 3));
    clr->g = t | (t>>6);

    t = ((Up_U32) (((c) & 0x001f) << 3));
    clr->b = t | (t>>5);

    return *clr;
}
gdi_color up_gd_color_from_rgb_16(GDIColor c)
{
    return (gdi_color) ((((c.b) & 0xf8) >> 3) | (((c.g) & 0xfc) << 3) | (((c.r) & 0xf8) << 8));
}

GDIColor up_gd_get_pixel_by_buffer_16(Up_U8 *buf,int x, int y,int width)
{
	return up_gd_color_to_rgb_16(*(Up_U16*) (buf + ((y * width+ x) << 1)));
}


void up_gd_put_pixel_by_buffer_16(Up_U8 *buf,int x, int y,int width, GDIColor cc)
{
    *(Up_U16*) (buf+ ((y * width + x) << 1)) = (Up_U16)up_gd_color_from_rgb_16(cc);
}

void MIOSHOW_HUE_TO_COLOR(S32 hue, S32 m1, S32 m2, U8 *V)
{
    S32 h;
    h = (hue + 360) % 360;
    if(h < 60)				/*60 = 360 / 6;*/
        *V = m1 + (m2 - m1) * h / 60;
    else if(h < 180)		/*180 = 360 / 2;*/
        *V = m2;
    else if(h < 240)		/*240 = 360 * 2 / 3;*/
        *V = m1 + (m2 - m1) * (240 - h) / 60;
    else
        *V = m1;
}

//ɫ�ʵ���
/* H [0, 360], L [0, 255], S [0, 255]. */
void MIOSHOW_editor_rgb_to_hsl(S32 r, S32 g, S32 b, 
                                      S32 *hue, S32 *saturation, S32 *lightness)
{
    U8 cmax, cmin, delta;
    S32 h, l, s;

    cmax = MIOSHOW_MAX(r, MIOSHOW_MAX(g, b));
    cmin = MIOSHOW_MIN(r, MIOSHOW_MIN(g, b));
    l = (cmax + cmin + 1) >> 1;

	if(cmax == cmin) {
		h = 0;
		s = 0;
	} else {
        delta = cmax - cmin;
        if(l < 128) {
            s = (delta << 8) / (cmax + cmin);
        } else {
            s = (delta << 8) / (511 - cmax - cmin);
        }

        if(r == cmax) {
            h = 60 * (g - b) / delta;
            if(g < b) {
                h += 360;
            }
        } else if(g == cmax) {
            h = 120 + 60 * (b - r) / delta;
        } else{
            h = 240 + 60 * (r - g) / delta;
        }
    }
    *hue = h;
    *saturation = s;
    *lightness = l;

}

/* H [0, 360], L [0, 255], S [0, 255]. */
void MIOSHOW_editor_hsl_to_rgb(S32 hue, S32 saturation, S32 lightness, 
                                      U8 *red, U8 *green, U8 *blue){
	S32 q, p;

	if(saturation == 0)
	{
		*red = *green = *blue = lightness;
	}
	else
	{
		if(lightness < 128)
			q = lightness + (lightness * saturation >> 8);
		else
			q  = lightness + saturation - (lightness * saturation >> 8);
		p = (lightness << 1) - q;
       
        MIOSHOW_HUE_TO_COLOR(hue + 120, p, q, red);
        MIOSHOW_HUE_TO_COLOR(hue, p, q, green);
        MIOSHOW_HUE_TO_COLOR(hue - 120, p, q, blue);
	}
}

void MIOSHOW_color_balance (ImageEditorArea *iea)
{
	Up_S32 i,ii,j,jj,w,h,cmax,cmin,hue,s,l;
	GDIColor pixel;
	U8 *buf0,*buf1; 
	Up_S32 r_n,g_n,b_n,light;
	
	ColorBalance *cb = (ColorBalance*)iea->para;

	ii = iea->rect->x;
	jj = iea->rect->y;
	h = iea->rect->width;
	w = iea->rect->height;
	buf0 = (U8*)iea->buf0;
	
	for(i = jj ;i<(jj+h);i++)
	{
		for(j = ii ;j <(ii+w);j++)
		{
			pixel = (GDIColor)up_gd_get_pixel_by_buffer_16(buf0,j,i,w);
			r_n = cb->r_lookup[pixel.r];
			g_n = cb->g_lookup[pixel.g];
			b_n = cb->b_lookup[pixel.b];
			if (cb->preserve_luminosity)
			{
				
				MIOSHOW_editor_rgb_to_hsl(r_n,g_n,b_n,&hue,&s,&l);
				cmax = MIOSHOW_MAX(pixel.r, MIOSHOW_MAX(pixel.g, pixel.b));
				cmin = MIOSHOW_MIN(pixel.r, MIOSHOW_MIN(pixel.g, pixel.b));
				light = (cmax + cmin + 1) >> 1;
				MIOSHOW_hsl_to_rgb(hue,s,light,&r_n,&g_n,&b_n);
				r_n = CLAMP0255(r_n);
				g_n = CLAMP0255(g_n);
				b_n = CLAMP0255(b_n);
			}	
			pixel.r = r_n;
			pixel.g = g_n;
			pixel.b = b_n;
			up_gd_put_pixel_by_buffer_16(buf0,j,i,w,pixel);
		}
	}

}

void MIOSHOW_color_balance_create_lookup_tables (ColorBalance *cb)
{
  Up_U16 *cyan_red_transfer[3];
  Up_U16 *magenta_green_transfer[3];
  Up_U16 *yellow_blue_transfer[3];
  Up_S32 i;
  Up_S32   r_n, g_n, b_n;


  /*  Prepare the transfer arrays  (for speed)  */
  cyan_red_transfer[MIOSHOW_SHADOWS] =
    (cb->cyan_red[MIOSHOW_SHADOWS] > 0) ? shadows_add : shadows_sub;

  cyan_red_transfer[MIOSHOW_MIDTONES] =
    (cb->cyan_red[MIOSHOW_MIDTONES] > 0) ? midtones_add : midtones_sub;

  cyan_red_transfer[MIOSHOW_HIGHLIGHTS] =
    (cb->cyan_red[MIOSHOW_HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;


  magenta_green_transfer[MIOSHOW_SHADOWS] =
    (cb->magenta_green[MIOSHOW_SHADOWS] > 0) ? shadows_add : shadows_sub;

  magenta_green_transfer[MIOSHOW_MIDTONES] =
    (cb->magenta_green[MIOSHOW_MIDTONES] > 0) ? midtones_add : midtones_sub;

  magenta_green_transfer[MIOSHOW_HIGHLIGHTS] =
    (cb->magenta_green[MIOSHOW_HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;


  yellow_blue_transfer[MIOSHOW_SHADOWS] =
    (cb->yellow_blue[MIOSHOW_SHADOWS] > 0) ? shadows_add : shadows_sub;

  yellow_blue_transfer[MIOSHOW_MIDTONES] =
    (cb->yellow_blue[MIOSHOW_MIDTONES] > 0) ? midtones_add : midtones_sub;

  yellow_blue_transfer[MIOSHOW_HIGHLIGHTS] =
    (cb->yellow_blue[MIOSHOW_HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;

  for (i = 0; i < 256; i++)
    {
      r_n = i;
      g_n = i;
      b_n = i;

      r_n += ((cb->cyan_red[MIOSHOW_SHADOWS] *
              cyan_red_transfer[MIOSHOW_SHADOWS][r_n])>>10);
      r_n = CLAMP0255 (r_n);

      r_n += ((cb->cyan_red[MIOSHOW_MIDTONES] *
              cyan_red_transfer[MIOSHOW_MIDTONES][r_n])>>10);
      r_n = CLAMP0255 (r_n);

      r_n += ((cb->cyan_red[MIOSHOW_HIGHLIGHTS] *
              cyan_red_transfer[MIOSHOW_HIGHLIGHTS][r_n])>>10);
      r_n = CLAMP0255 (r_n);

      g_n += ((cb->magenta_green[MIOSHOW_SHADOWS] *
              magenta_green_transfer[MIOSHOW_SHADOWS][g_n])>>10);
      g_n = CLAMP0255 (g_n);

      g_n += ((cb->magenta_green[MIOSHOW_MIDTONES] *
              magenta_green_transfer[MIOSHOW_MIDTONES][g_n])>>10);
      g_n = CLAMP0255 (g_n);

      g_n += ((cb->magenta_green[MIOSHOW_HIGHLIGHTS] *
              magenta_green_transfer[MIOSHOW_HIGHLIGHTS][g_n])>>10);
      g_n = CLAMP0255 (g_n);

      b_n += ((cb->yellow_blue[MIOSHOW_SHADOWS] *
              yellow_blue_transfer[MIOSHOW_SHADOWS][b_n])>>10);
      b_n = CLAMP0255 (b_n);

      b_n += ((cb->yellow_blue[MIOSHOW_MIDTONES] *
              yellow_blue_transfer[MIOSHOW_MIDTONES][b_n])>>10);
      b_n = CLAMP0255 (b_n);

      b_n += ((cb->yellow_blue[MIOSHOW_HIGHLIGHTS] *
              yellow_blue_transfer[MIOSHOW_HIGHLIGHTS][b_n])>>10);
      b_n = CLAMP0255 (b_n);

      cb->r_lookup[i] = r_n;
      cb->g_lookup[i] = g_n;
      cb->b_lookup[i] = b_n;
    }
}

void color_balance(Up_U8 preserve_luminosity,Up_S32 cyan_red_p[3],Up_S32  magenta_green_p[3],Up_S32  yellow_blue_p[3],ImageEditorArea *iea)
{
	Up_S32 br,co;
	
	ColorBalance cb;

	cb.cyan_red[0] = cyan_red_p[0];
	cb.magenta_green[0] = magenta_green_p[0];
	cb.yellow_blue[0] = yellow_blue_p[0];

	cb.cyan_red[1] = cyan_red_p[1];
	cb.magenta_green[1] = magenta_green_p[1];
	cb.yellow_blue[1] = yellow_blue_p[1];

	cb.cyan_red[2] = cyan_red_p[1];
	cb.magenta_green[2] = magenta_green_p[1];
	cb.yellow_blue[2] = 	yellow_blue_p[1];

	cb.preserve_luminosity = preserve_luminosity;
	
	MIOSHOW_color_balance_transfer_init();	
	MIOSHOW_color_balance_create_lookup_tables(&cb);
	//iea.buf0 = (Up_U8*)up_get_layer_buffer(0);
	//iea.buf1 = (Up_U8*)up_get_layer_buffer(1);
	//iea.rect = &GIP->editorArea->area;
	iea->para = (void*)&cb;
	MIOSHOW_color_balance(iea);
	MIOSHOW_color_balance_transfer_exit();
}

GDIColor up_rgb565_to_rgb8_gray (GDIColor rgb)
{
	GDIColor rgbtmp;
	rgbtmp.r = rgbtmp.g = rgbtmp.b = (77*rgb.r+151*rgb.g+28*rgb.b)>>8;
	return rgbtmp;
}

/*
 * The equations: g(r) = exp (- r^2 / (2 * sigma^2))
 *                   r = sqrt (x^2 + y ^2)
 */
void MIOSHOW_make_curve(double sigma, S32 *length,S32 *curve)
{
	double  sigma2, l;
	S32     temp;
	S32     i, n, ll;
    S32    *temp_curve;

	sigma2 = 2 * sigma * sigma;
	l = sqrt(-sigma2 * log(1.0 / 255.0));

	n = (S32)(ceil(l) * 2);
	if ((n % 2) == 0)
		n += 1;

	*length = n / 2;
    ll = n / 2;

    temp_curve = (S32 *)curve;
	temp_curve += ll;
	temp_curve[0] = 255;

	for (i = 1; i <= ll; i++)
	{
		temp = (S32)(exp(- (i * i) / sigma2) * 255);
		temp_curve[-i] = temp;
		temp_curve[i] = temp;
	}

}

void MIOSHOW_gaussia_blur(ImageEditorArea *iea)
{
    U16 *buf_ptr, *temp_buf, *dst_data, *src_data, wPixel, *column_ptr;
    U16 *src_buf;
    S32 width, height, length, w, h;
	
    S32 i, tmp = 0, cr, cg, cb, cur_radius;
    U32 sumr = 0, averr = 0,sumg = 0,averg = 0,sumb = 0,averb = 0,MIOSHOW_sum = 0;
    S32 ri;
    double radius, std_dev;
    U16 *temp_line;
    S32  cur_min, cur_max;
    S32 *cur_curve, * curve_ptr, curve_value;
    SoftGlowData *sgd = (SoftGlowData*)iea->para;
	width = iea->rect->width;
    height = iea->rect->height;
    if(sgd->blur <= 0)
        return;

    temp_line = (U16*)malloc(480*sizeof(U16));
    Up_Memcpy((void*)iea->buf1,(void*)iea->buf0,width*height*BPP);
    buf_ptr = (U16 *)iea->buf0;//dst
    temp_buf = (U16 *)iea->buf1;//src

    MIOSHOW_sum = 0;
    radius = abs(sgd->blur) * 1.4;
    std_dev = sqrt(-(radius * radius) / (2 * log(1.0 / 255.0)));
    MIOSHOW_make_curve(std_dev, &length,(S32*)sgd->curve);
    cur_curve = (S32*)sgd->curve; 
    cur_radius = length*2 + 1;

    /*  First, the vertical pass  */
    for(w = 0; w < width; w++) {
        dst_data = buf_ptr + w+iea->rect->x+iea->rect->y*width;
        src_data = temp_buf + w+ iea->rect->x+iea->rect->y*width;
        column_ptr = temp_line;
        for(h = 0; h < height; h++) {
            *column_ptr = *src_data;
            column_ptr++;
            src_data += width;//must be lcd width
        }
        
        for(h = 0; h < height; h++) {
            ri = h - length;
            cur_min = MIOSHOW_MAX(0, ri);
            cur_max = MIOSHOW_MIN(height, ri + cur_radius);
            src_buf = temp_line + cur_min;
            curve_ptr = cur_curve + (cur_min - ri);
            for(i = cur_max - cur_min; i > 0; i--) {                
                wPixel = *src_buf;
                src_buf++;
                curve_value = *curve_ptr;
                curve_ptr++;
                sumr += MIOSHOW_RGB565_GET_R(wPixel) * curve_value;
                sumg += MIOSHOW_RGB565_GET_G(wPixel) * curve_value;
                sumb += MIOSHOW_RGB565_GET_B(wPixel) * curve_value;
		   MIOSHOW_sum += curve_value;		
            }
		averr = sumr / MIOSHOW_sum;
		averg = sumg / MIOSHOW_sum;
		averb = sumb / MIOSHOW_sum;			
		*dst_data = MIOSHOW_RGB565(averr,averg,averb);
		dst_data += width;
		averr = averg =averb =0;
		sumr = sumg = sumb = 0;
		MIOSHOW_sum = 0;
        }
	}

    MIOSHOW_sum = 0;
    
    /*  Now the horizontal pass  */
    for(h = 0; h < height; h++) {
        Up_Memcpy(temp_line, buf_ptr + h * width+iea->rect->x+iea->rect->y*width, width * 2);
        src_data = temp_buf + h * width+iea->rect->x+iea->rect->y*width;
        dst_data = buf_ptr + h * width+iea->rect->x+iea->rect->y*width;
        for(w = 0; w < width; w++) {
            ri = w - length;
            cur_min = MIOSHOW_MAX(0, ri);
            cur_max = MIOSHOW_MIN(width, ri + cur_radius);
            src_buf = temp_line + cur_min;
            curve_ptr = cur_curve + (cur_min - ri);
            for(i = cur_max - cur_min; i > 0; i--) { 
                wPixel = *src_buf;
                src_buf++;
                curve_value = *curve_ptr;
                curve_ptr++;
                sumr += MIOSHOW_RGB565_GET_R(wPixel) * curve_value;
                sumg += MIOSHOW_RGB565_GET_G(wPixel) * curve_value;
                sumb += MIOSHOW_RGB565_GET_B(wPixel) * curve_value;
		   MIOSHOW_sum += curve_value;	               
            }
            
		averr = sumr / MIOSHOW_sum;
		averg = sumg / MIOSHOW_sum;
		averb = sumb / MIOSHOW_sum;			
		*dst_data = MIOSHOW_RGB565(averr,averg,averb);        
		averr = averg =averb =0;
		sumr = sumg = sumb = 0;
		MIOSHOW_sum = 0;
            dst_data++;  
            src_data++;
        }
	} 
	free((void*)temp_line);
	
}

void MIOSHOW_dog(ImageEditorArea *iea)
{
	Up_S32 i,ii,j,jj,w,h;
	GDIColor pixel1,pixel2,pixel;
	Up_U8 *buf0,*buf1;
	MIOSHOW_gaussia_blur(iea);
	ii = iea->rect->x;
	jj = iea->rect->y;
	h = iea->rect->height;
	w = iea->rect->width;
	buf0 = iea->buf0;
	buf1 = iea->buf1;
	for(i = jj ;i<(jj+h);i++)
	{
		for(j = ii ;j <(ii+w);j++)
		{
			pixel1 = up_gd_get_pixel_by_buffer_16(buf0,j,i,w);
			pixel2 = up_gd_get_pixel_by_buffer_16(buf1,j,i,w);
			pixel.r = (255-CLAMP((pixel1.r - pixel2.r),0,255));
			pixel.g = (255-CLAMP(pixel1.g - pixel2.g,0,255));
			pixel.b = (255-CLAMP(pixel1.b - pixel2.b,0,255));
			up_gd_put_pixel_by_buffer_16(buf0,j,i,w,up_rgb565_to_rgb8_gray(pixel));
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//����Ϊ�������е����Ч��///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
void exe_tiliang(ImageEditorArea *iea)
{

	change_bc(10,10,iea);
}

void exe_fugu(ImageEditorArea *iea)
{
	Up_S32 cyan_red[3] = {0,0,0};
	Up_S32  magenta_green[3] ={0,0,0};
	Up_S32  yellow_blue[3]={10,0,15};	
	//redoundo_read_top_to_memory(get_undo_stack());	
	addcolor(60,70,150,iea);
	change_bc(-5,-5,iea);
	color_balance(1,cyan_red,magenta_green,yellow_blue,iea);		
}

void exe_heibai(ImageEditorArea *iea)
{
	addcolor(0,0,255,iea);
	change_bc(-25,20,iea);		
}

void exe_qiuse(ImageEditorArea *iea)
{
	Up_S32 cyan_red[3] = {10,0,10};
	Up_S32  magenta_green[3] ={0,0,0};
	Up_S32  yellow_blue[3]={-5,0,-5};
	addcolor(240,110,100,iea);
	change_bc(5,0,iea);	
	color_balance(0,cyan_red,magenta_green,yellow_blue,iea);		
}

void exe_sumiao(ImageEditorArea *iea)
{
	SoftGlowData sgd;
	
	sgd.blur = 20;
	sgd.light = 0;
	sgd.curve = (void*)malloc(1024 * 2);
	iea->para = (void*)&sgd;
	MIOSHOW_dog(iea);
	free((void*)sgd.curve);
	change_bc(-40,70,iea);	
}

void exe_fenhong(ImageEditorArea *iea)
{
	Up_S32 cyan_red[3] = {-5,5,5};
	Up_S32  magenta_green[3] ={0,-5,-5};
	Up_S32  yellow_blue[3]={5,0,5};
	addcolor(260,100,100,iea);
	change_bc(10,0,iea);	
	color_balance(0,cyan_red,magenta_green,yellow_blue,iea);
}
void exe_laozhaopian(ImageEditorArea *iea)
{
	Up_S32 cyan_red[3] = {15,10,5};
	Up_S32  magenta_green[3] ={-5,0,-5};
	Up_S32  yellow_blue[3]={-15,-20,-15};
	addcolor(0,0,230,iea);
	change_bc(-15,0,iea);
	color_balance(0,cyan_red,magenta_green,yellow_blue,iea);		
}

void exe_abao(ImageEditorArea *iea)
{
	Up_S32 cyan_red[3] = {0,-60,0};
	Up_S32  magenta_green[3] ={0,0,0};
	Up_S32  yellow_blue[3]={0,0,0};
	addcolor(180,50,90,iea);
	//change_bc(0,0,iea);
	color_balance(1,cyan_red,magenta_green,yellow_blue,iea);		
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_longcheer_mioshow_graphics_SpecialEffect */

#ifndef _Included_ivan_cheng_tuqu_graphics_SpecialEffect
#define _Included_ivan_cheng_tuqu_graphics_SpecialEffect
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_longcheer_mioshow_graphics_SpecialEffect
 * Method:    change_studio_ext_Jni
 * Signature: ([BI[BI[B)V
 */
JNIEXPORT void JNICALL Java_ivan_cheng_tuqu_graphics_SpecialEffect_ChangeStudioExtJni
  (JNIEnv *env, jobject j, jshortArray pbyInBuffer, jint nInBufferLength, jshortArray pbyOutBuffer, 
  jint nOutBufferLength, jint width, jint height,jint type)
  {
		 
	jshort *in=(*env)->GetShortArrayElements(env,pbyInBuffer, 0);//inָ��������ַ
	jshort *out=(*env)->GetShortArrayElements(env,pbyOutBuffer, 0);//inָ��������ַ

	U16 p = type;
	
	ImageEditorArea iea;
	UPRect psRect = {0,0,width,height};
	iea.buf0 = (void*)in;
	iea.buf1 = (void*)out;	
	iea.rect = &psRect;
	iea.para = (void*)&p;
	
	//uuphoto_editor_function_change_studio_ext(&iea);
	//exe_tiliang(&iea);
	exe_fugu(&iea);
	
	//(*env)->ReleaseShortArrayElements(env,in,0,0);
	//(*env)->ReleaseShortArrayElements(env,out,0,0);
  }
  //���Ч��
  JNIEXPORT void JNICALL Java_ivan_cheng_tuqu_graphics_SpecialEffect_SoftGlowJni
  (JNIEnv *env, jobject j, jshortArray pbyInBuffer, jint nInBufferLength, jshortArray pbyOutBuffer, 
  jint nOutBufferLength, jint width, jint height,jint blur,jint light)
  {
		 
	jshort *in=(*env)->GetShortArrayElements(env,pbyInBuffer, 0);//inָ��������ַ
	jshort *out=(*env)->GetShortArrayElements(env,pbyOutBuffer, 0);//inָ��������ַ

	ImageEditorArea iea;
	SoftGlowData sgd;
	UPRect psRect = {0,0,width,height};
	iea.buf0 = (void*)in;
	iea.buf1 = (void*)out;	
	iea.rect = &psRect;
	//sgd.blur = 8;
	//sgd.light = 75;
	sgd.blur = blur;
	sgd.light = light;
	sgd.curve = (void*)malloc(1024 * 2);
	iea.para = (void*)&sgd;
	uuphoto_editor_function_softglow(&iea);
	free((void*)sgd.curve);
	
	
	//(*env)->ReleaseShortArrayElements(env,in,0,0);
	//(*env)->ReleaseShortArrayElements(env,out,0,0);
  }
  //���벹��
  JNIEXPORT void JNICALL Java_ivan_cheng_tuqu_graphics_SpecialEffect_FillLightJni
  (JNIEnv *env, jobject j, jshortArray pbyInBuffer, jint nInBufferLength, jshortArray pbyOutBuffer, 
  jint nOutBufferLength, jint width, jint height,jint light_delta)
  {
		 
	jshort *in=(*env)->GetShortArrayElements(env,pbyInBuffer, 0);//inָ��������ַ
	jshort *out=(*env)->GetShortArrayElements(env,pbyOutBuffer, 0);//inָ��������ַ

	
	ImageEditorArea iea;
	//S32 light_delta = 125;

	UPRect psRect = {0,0,width,height};
	iea.buf0 = (void*)in;
	iea.buf1 = (void*)out;	
	iea.rect = &psRect;
	iea.para = (void*)&light_delta;

	uuphoto_editor_function_fill_light(&iea);
	
	
	//(*env)->ReleaseShortArrayElements(env,in,0,0);
	//(*env)->ReleaseShortArrayElements(env,out,0,0);
  }
  
  //����ɫ��
  JNIEXPORT void JNICALL Java_ivan_cheng_tuqu_graphics_SpecialEffect_ChangeHueJni
  (JNIEnv *env, jobject j, jshortArray pbyInBuffer, jint nInBufferLength, jshortArray pbyOutBuffer, 
  jint nOutBufferLength, jint width, jint height,jint hue_delta)
  {
		 
	jshort *in=(*env)->GetShortArrayElements(env,pbyInBuffer, 0);//inָ��������ַ
	jshort *out=(*env)->GetShortArrayElements(env,pbyOutBuffer, 0);//inָ��������ַ

	
	ImageEditorArea iea;
	//S32 hue_delta = 50;
	UPRect psRect = {0,0,width,height};
	iea.buf0 = (void*)in;
	iea.buf1 = (void*)out;	
	iea.rect = &psRect;
	iea.para = (void*)&hue_delta;

	uuphoto_editor_function_change_hue_ext(&iea);
	
	
	//(*env)->ReleaseShortArrayElements(env,in,0,0);
	//(*env)->ReleaseShortArrayElements(env,out,0,0);
  }
  
  //���������Ч
  JNIEXPORT void JNICALL Java_ivan_cheng_tuqu_graphics_SpecialEffect_ComboSpecEffectJni
  (JNIEnv *env, jobject j, jshortArray pbyInBuffer, jint nInBufferLength, jshortArray pbyOutBuffer, 
  jint nOutBufferLength, jint width, jint height,jint type)
  {
		 
	jshort *in=(*env)->GetShortArrayElements(env,pbyInBuffer, 0);//inָ��������ַ
	jshort *out=(*env)->GetShortArrayElements(env,pbyOutBuffer, 0);//inָ��������ַ

	ImageEditorArea iea;
	
	UPRect psRect = {0,0,width,height};
	iea.buf0 = (void*)in;
	iea.buf1 = (void*)out;	
	iea.rect = &psRect;
	
	switch(type)
	{
		case 0:
			exe_tiliang(&iea);
			break;
		case 1:
			exe_fugu(&iea);
			break;
		case 2:
			exe_heibai(&iea);
			break;
		case 3:
			exe_qiuse(&iea);
			break;
		case 4:
			exe_sumiao(&iea);
			break;
		case 5:
			exe_fenhong(&iea);
			break;
		case 6:
			exe_laozhaopian(&iea);
			break;
		case 7:
			exe_abao(&iea);
			break;
		default:
			break;
	};	
	//(*env)->ReleaseShortArrayElements(env,in,0,0);
	//(*env)->ReleaseShortArrayElements(env,out,0,0);
  }
  
#ifdef __cplusplus
}
#endif
#endif

